package com.example.mvvm.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Looper;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import com.example.mvvm.R;
import com.example.mvvm.mode.Ball;
import com.example.mvvm.mode.TaskModel;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Time: 5/24/2021 16:53
 * Author: TAO
 * Description:
 */
public class BallView3 extends View {
    private TextPaint textPaint;// 文字
    private Paint ballPaint;
    private Random random;// 随机数，用于生成速度，位置
    private Ball[] ballArr;
    private int minSpeed = 5; // 小球最小移动速度
    private int maxSpeed = 20; // 小球最大移动速度
    private int mWidth = 128;
    private int mHeight = 128;
    private int mCount = 1;
    public ArrayList<Ball> bList;//保存设置圆心的小球集合
    private List<TaskModel> datas = new ArrayList<>();

    public BallView3(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    private void initPaint() {
        bList = new ArrayList<>();
        // 初始化随机数
        random = new Random();

        // 初始化文字画笔
        textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.parseColor("#191833"));
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTextSize(24);

        ballPaint = new Paint();
        ballPaint.setStyle(Paint.Style.FILL);
        ballPaint.setColor(Color.parseColor("#edfdff"));

        ballArr = new Ball[mCount];
        for (int i = 0; i < mCount; i++) {
            ballArr[i] = new Ball();
            float speedX = (random.nextInt(maxSpeed - minSpeed + 1) + 5) / 10f;
            float speedY = (random.nextInt(maxSpeed - minSpeed + 1) + 5) / 10f;
            ballArr[i].setVx(random.nextBoolean() ? speedX : -speedX);
            ballArr[i].setVy(random.nextBoolean() ? speedY : -speedY);
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = resolveSize(mWidth, widthMeasureSpec);
        mHeight = resolveSize(mHeight, heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
        // 初始化圆的半径和圆心
        for (int i = 0; i < mCount; i++) {
            ballArr[i].setRadius(mWidth / 14);
            // 初始化圆心的位置， x最小为 radius， 最大为mwidth- radius
            ballArr[i].setCx(100f);
            ballArr[i].setCy(100f);
            bList.add(ballArr[i]);
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        long startTime = System.currentTimeMillis();
        if (datas.size() > 0) {
            for (int i = 0; i < datas.size(); i++) {
                Ball ball = ballArr[i];
//                canvas.drawCircle(ball.getCx(), ball.getCy(), ball.getRadius(), ballPaint);
                Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.qiuqiu_1);
                canvas.drawBitmap(bitmap,ball.getCx(),ball.getCy(),ballPaint);



                Rect rect = new Rect((int) (ball.getCx() - ball.getRadius()), (int) (ball.getCy() - ball.getRadius()), (int) (ball.getCx() + ball.getRadius()), (int) (ball.getCy() + ball.getRadius()));
                Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
                float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
                float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
                int baseLineY = (int) (rect.centerY() + top);//基线中间点的y轴计算公式
                String str = datas.get(i).getName();
                ball.setContent(datas.get(i).getName());
                ball.setTaskId(datas.get(i).getId());
                StaticLayout layout = new StaticLayout(str, textPaint, ball.getRadius(), Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
                canvas.save();
                canvas.translate(rect.centerX(), baseLineY);//从100，100开始画
                layout.draw(canvas);
                canvas.restore();//别忘了restore
            }

            for (int i = 0; i < datas.size(); i++) {
                Ball ball = ballArr[i];
                collisionDetectingAndChangeSpeed(ball); // 碰撞边界的计算
                collisionDetectingAndChangeSpeeds(ball, i);
//                ball.move(); // 移动
            }

            long stopTime = System.currentTimeMillis();
            long runTime = stopTime - startTime;
            // 16毫秒执行一次
            postInvalidateDelayed(Math.abs(runTime - 16));
        }
    }


    /**
     * 气泡碰撞算法
     *
     * @param ball
     * @param position
     */
    private void collisionDetectingAndChangeSpeeds(Ball ball, int position) {
        float cx = ball.getCx();
        float cy = ball.getCy();
        int cr = ball.getRadius();
        for (int i = 0; i < mCount; i++) {
            if (i == position) {
                return;
            }
            Ball balls = ballArr[i];
            if (checkCollideCircle(cx, cy, cr, balls.getCx(), balls.getCy(), balls.getRadius())) {
                ball.setVx(-ball.getVx());
                ball.setVy(-ball.getVy());
                balls.setVx(-balls.getVx());
                balls.setVy(-balls.getVy());
            }
        }
    }

    /**
     * 两个圆的碰撞检测
     *
     * @param x1
     * @param y1
     * @param r1
     * @param x2
     * @param y2
     * @param r2
     * @return
     */
    private boolean checkCollideCircle(float x1, float y1, int r1, float x2,
                                       float y2, int r2) {
        boolean iscollide = false;
        //两点之间的距离 小于两半径之和就发生了碰撞
        if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) <= r1 + r2) {
            iscollide = true;
        } else {
            iscollide = false;
        }
        return iscollide;
    }

    // 判断球是否碰撞碰撞边界
    public void collisionDetectingAndChangeSpeed(Ball ball) {
        int left = getLeft();
        int top = getTop();
        int right = getRight();
        int bottom = getBottom();

        float speedX = ball.getVx();
        float speedY = ball.getVy();

        // 碰撞左右，X的速度取反。 speed的判断是防止重复检测碰撞，然后黏在墙上了=。=
        if (ball.left() <= left && speedX < 0) {
            ball.setVx(-ball.getVx());
        } else if (ball.top() <= top && speedY < 0) {
            ball.setVy(-ball.getVy());
            ;
        } else if (ball.right() >= right && speedX > 0) {
            ball.setVx(-ball.getVx());
        } else if (ball.bottom() >= bottom && speedY > 0) {
            ball.setVy(-ball.getVy());
        }
    }

    public void setData(List<TaskModel> mList) {
        this.mCount = mList.size();
        this.datas = mList;
        if (Looper.getMainLooper() == Looper.myLooper()) {
            invalidate();
        } else {
            postInvalidate();
        }
    }
}
